package com.cs.vessel.breakdown.view;

import java.util.Iterator;
import java.util.List;
import java.util.UUID;

import org.eclipse.emf.cdo.util.CommitException;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.dialogs.IInputValidator;
import org.eclipse.jface.dialogs.InputDialog;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.ViewPart;

import com.cs.vessel.breakdown.Activator;
import com.cs.vessel.breakdown.CDOHibernateUtil;
import com.cs.vessel.breakdown.LaunchAccidentNewWizardAction;
import com.cs.vessel.breakdown.Messages;
import com.cs.vessel.breakdown.view.providers.ComponentViewContentProvider;
import com.cs.vessel.breakdown.view.providers.ComponentViewLabelProvider;
import com.sc.vessel.info.editor.AccidentEditor;
import com.sc.vessel.info.editor.AccidentInput;
import com.sc.vessel.info.model.breakdown.BreakdownFactory;
import com.sc.vessel.info.model.breakdown.Component;

public class NavigationView extends ViewPart {

    public static final String ID = "com.cs.vessel.breakdown.navigationView"; //$NON-NLS-1$

    private TreeViewer viewer;

    private Action doubleClickAction;

    private Action createComponentAction;

    private Action editComponentAction;

    private Action refreshAction;

    private LaunchAccidentNewWizardAction launchWizardAction;

    /**
     * This is a callback that will allow us to create the viewer and initialize it.
     */
    public void createPartControl(Composite parent) {
        viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);
        viewer.setContentProvider(new ComponentViewContentProvider());
        viewer.setLabelProvider(new ComponentViewLabelProvider());
        Component component = CDOHibernateUtil.getRootCompomnent();
        viewer.setInput(new Object[] { component });
        makeActions();
        hookContextMenu();
        hookDoubleClickAction();
        openInitEditor(component);
    }

    /**
     * DOC liaoqc Comment method "openEditor".
     * 
     * @param component
     */
    private void openInitEditor(Component component) {
        viewer.setSelection(new StructuredSelection(component));
        doubleClickAction.run();
    }

    /**
     * DOC liaoqc Comment method "hookContextMenu".
     */
    private void hookContextMenu() {
        MenuManager mgr = new MenuManager();
        mgr.setRemoveAllWhenShown(true);
        mgr.addMenuListener(new IMenuListener() {

            public void menuAboutToShow(IMenuManager manager) {
                fillContextMenu(manager);
            }
        });
        Menu menu = mgr.createContextMenu(viewer.getControl());
        viewer.getControl().setMenu(menu);
        getSite().registerContextMenu(mgr, viewer);
    }

    /**
     * DOC liaoqc Comment method "fillContextMenu".
     * 
     * @param manager
     */
    protected void fillContextMenu(IMenuManager manager) {
        manager.add(createComponentAction);
        manager.add(launchWizardAction);
        manager.add(new Separator());
        manager.add(editComponentAction);
        manager.add(new Separator());
        manager.add(refreshAction);
    }

    private void makeActions() {

        createComponentAction = new Action() {

            public void run() {
                ISelection selection = viewer.getSelection();
                Object obj = ((IStructuredSelection) selection).getFirstElement();
                if (obj instanceof Component) {
                    InputDialog inputDialog = new InputDialog(getSite().getShell(), Messages.NavigationView_1,
                            Messages.NavigationView_2, "", new IInputValidator() { //$NON-NLS-2$ //$NON-NLS-1$ //$NON-NLS-1$ //$NON-NLS-1$

                                @Override
                                public String isValid(String newText) {
                                    if (newText == null || "".equals(newText)) { //$NON-NLS-1$
                                        return Messages.NavigationView_5;
                                    }
                                    return null;
                                }
                            });
                    inputDialog.open();
                    String newName = inputDialog.getValue();
                    if (newName == null || "".equals(newName)) { //$NON-NLS-1$
                        return;
                    }
                    Component component = (Component) obj;
                    // added component
                    Component childComponent = BreakdownFactory.eINSTANCE.createComponent();
                    childComponent.setName(newName);
                    String itemId = UUID.randomUUID().toString();
                    childComponent.setItemId(itemId);
                    try {
                        CDOHibernateUtil.addComponent(component, childComponent);
                    } catch (CommitException e) {
                        // add failed log
                        e.printStackTrace();
                    }
                    viewer.refresh(component);
                    viewer.expandToLevel(component, TreeViewer.ALL_LEVELS);
                    // refresh the tree
                    setSelection(component, itemId);
                }
            }
        };

        createComponentAction.setText(Messages.NavigationView_7);
        createComponentAction.setToolTipText(Messages.NavigationView_8);
        createComponentAction.setImageDescriptor(Activator.getImageDescriptor("/icons/component.gif")); //$NON-NLS-1$

        doubleClickAction = new Action() {

            public void run() {
                ISelection selection = viewer.getSelection();
                Object obj = ((IStructuredSelection) selection).getFirstElement();
                if (obj instanceof Component) {
                    Component component = (Component) obj;
                    AccidentInput accidentInput = new AccidentInput(component);
                    IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
                    try {
                        page.openEditor(accidentInput, AccidentEditor.ID);
                    } catch (PartInitException e) {
                        System.err.println(e.getMessage());
                    }
                }
            }
        };

        launchWizardAction = new LaunchAccidentNewWizardAction(Messages.ApplicationActionBarAdvisor_create_accident,
                getViewSite().getWorkbenchWindow()) {

            /*
             * (non-Javadoc)
             * 
             * @see com.cs.vessel.breakdown.LaunchAccidentNewWizardAction#run()
             */
            @Override
            public void run() {
                ISelection selection = viewer.getSelection();
                setSelection((IStructuredSelection) selection);
                super.run();
            }

        };
        launchWizardAction.setText(Messages.NavigationView_11);
        launchWizardAction.setDescription(Messages.NavigationView_12);
        launchWizardAction.setImageDescriptor(Activator.getImageDescriptor("/icons/accident.gif")); //$NON-NLS-1$

        editComponentAction = new Action() {

            /*
             * (non-Javadoc)
             * 
             * @see org.eclipse.jface.action.Action#run()
             */
            @Override
            public void run() {
                ISelection selection = viewer.getSelection();
                Object obj = ((IStructuredSelection) selection).getFirstElement();
                if (obj instanceof Component) {
                    Component component = (Component) obj;
                    InputDialog inputDialog = new InputDialog(getSite().getShell(), Messages.NavigationView_13, Messages.NavigationView_2,
                            component.getName(), new IInputValidator() { //$NON-NLS-2$ //$NON-NLS-1$ //$NON-NLS-1$

                                @Override
                                public String isValid(String newText) {
                                    if (newText == null || "".equals(newText)) { //$NON-NLS-1$
                                        return Messages.NavigationView_5;
                                    }
                                    return null;
                                }
                            });
                    inputDialog.open();
                    String newName = inputDialog.getValue();
                    if (newName == null || "".equals(newName) || component.getName().equals(newName)) { //$NON-NLS-1$
                        return;
                    }
                    try {
                        CDOHibernateUtil.editComponentName(component, newName);
                    } catch (CommitException e) {
                        // add failed log
                        e.printStackTrace();
                    }
                    viewer.refresh();
                }
            }
        };
        editComponentAction.setText(Messages.NavigationView_3);
        editComponentAction.setToolTipText(Messages.NavigationView_4);
        editComponentAction.setImageDescriptor(Activator.getImageDescriptor("/icons/component.gif")); //$NON-NLS-1$

        refreshAction = new Action() {

            /*
             * (non-Javadoc)
             * 
             * @see org.eclipse.jface.action.Action#run()
             */
            @Override
            public void run() {
                viewer.refresh();
            }
        };

        refreshAction.setText(Messages.NavigationView_9);
        refreshAction.setDescription(Messages.NavigationView_9);
        refreshAction.setImageDescriptor(Activator.getImageDescriptor("/icons/refresh_blue.gif")); //$NON-NLS-1$
    }

    private void setSelection(Component component, String itemId) {
        Component currentComponent = getCurrentComponent(component, itemId);
        viewer.setSelection(new StructuredSelection(currentComponent), true);
    }

    /**
     * DOC liaoqc Comment method "getCurrentComponent".
     * 
     * @param itemId
     * @return
     */
    public static Component getCurrentComponent(Component component, String itemId) {

        if (component.getItemId().equals(itemId)) {
            return component;
        }
        List<Component> components = component.getComponents();
        for (Iterator<Component> iterator = components.iterator(); iterator.hasNext();) {
            Component curr = (Component) iterator.next();
            Component result = getCurrentComponent(curr, itemId);
            if (result == null) {
                continue;
            } else
                return result;
        }
        return null;
    }

    /**
     * DOC liaoqc Comment method "hookDoubleClickAction".
     */
    private void hookDoubleClickAction() {
        viewer.addDoubleClickListener(new IDoubleClickListener() {

            public void doubleClick(DoubleClickEvent event) {
                doubleClickAction.run();
            }
        });

    }

    /**
     * Passing the focus request to the viewer's control.
     */
    public void setFocus() {
        viewer.getControl().setFocus();
    }

}
